package com.androwit.engine.mapping.auto;

import java.util.HashMap;
import java.util.Map;

import com.androwit.engine.mapping.MappingFieldsDefiner;

/**
 * 
 * 
 * @author Zied Hamdi http://1vu.fr
 * 
 * @param <J>
 * @param <K>
 * @param <V>
 * @param <C>
 *          the type of the key to use in caching
 */
public abstract class AbstractMappingFieldsDefinerCache<J, K, V, C> {
	protected Map<C, MappingFieldsDefiner<J, K, V>> cache = new HashMap<C, MappingFieldsDefiner<J, K, V>>();

	/**
	 * returns the instance responsible for the fields definition
	 * 
	 * @param clazz
	 *          the key to analyse
	 * @return fields definition for key
	 */
	protected abstract MappingFieldsDefiner<J, K, V> loadMappingFieldsDefiner(
			C clazz);

	public MappingFieldsDefiner<J, K, V> getMappingFieldsDefiner(C key) {
		MappingFieldsDefiner<J, K, V> mappingFieldsDefiner = cache.get(key);
		if (mappingFieldsDefiner == null) {
			mappingFieldsDefiner = loadMappingFieldsDefiner(key);
			if (mappingFieldsDefiner == null) {
				throw new IllegalStateException(
						"The method loadMappingFieldsDefiner is not allowed to return null. asked for key "
								+ key);
			}

			cache.put(key, mappingFieldsDefiner);
		}
		return mappingFieldsDefiner;
	}

	public void clear() {
		cache.clear();
	}

}
